import React, { useState } from 'react';
import {
  Box,
  CardBase,
  GridCarousel,
  GridItem,
  LoadingIcon,
  MainButton,
  Text,
  Tooltip,
  useViewport,
} from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import Authentication from 'beta/store/authentication';
import { cloneDeep } from 'lodash';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import {
  ConnectionOptions,
  ConnectionReason,
  ConnectionSpeed,
  ConnectivityOptionsType,
  FiberService,
  ProviderAddress,
  ProviderApartment,
  useConnectionAvailabilityApartmentsQuery,
  useFiberConnectivityOptionsQuery,
  useFiberOrderQuery,
  useServiceQuery,
  useUpdateFiberConnectivityOptionsMutation,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

type IPropertiesProps = {
  authentication?: Authentication;
  color?: MainColorType;
  address: ProviderAddress;
  onSelectProperty: (property: ProviderApartment, option: ConnectionOptions) => void;
};

const Properties = ({ color, address, onSelectProperty, authentication }: IPropertiesProps) => {
  const { t } = useTranslation('flutningur');
  const { isSmall, isMedium, isXLarge } = useViewport();
  const itemsPerPage = isXLarge ? 15 : 50;
  const negativeMarginForCarousel = isSmall ? '-24px' : '-152px';

  const { query } = useRouter();
  const serviceId = query.serviceId as string;
  const [apartmentSlide, setApartmentSlide] = useState<number>();

  const [message, setMessage] = useState('');
  const [selectedApartment, setSelectedApartment] = useState<ProviderApartment>();
  const [selectedProvider, setSelectedProvider] = useState<ConnectionOptions>();

  const { __typename, city, line, ...input } = address;

  const { data: fiberData } = useServiceQuery({
    variables: {
      serviceId,
    },
  });

  const fiberSerivce: FiberService | undefined =
    fiberData?.service.__typename === 'FiberService'
      ? (fiberData.service as FiberService)
      : undefined;

  const { data: fiberOrderData } = useFiberOrderQuery({
    variables: {
      input: {
        fiberOrderId: fiberSerivce?.fiberOrderId,
      },
    },
  });

  const [updateFiberConnectivityOptions] = useUpdateFiberConnectivityOptionsMutation();

  const isCompanyOrder = fiberOrderData?.fiberOrder?.isCompanyOrder;

  const connectionSpeed = fiberSerivce?.connectionSpeed?.includes('1Gb/s')
    ? ConnectionSpeed.OneGbPs
    : ConnectionSpeed.TwoPointFiveGbPs;

  const { data, loading } = useConnectionAvailabilityApartmentsQuery({
    variables: { input },
  });

  const { data: connectivityOptions, loading: loadingConnectivityOptions } =
    useFiberConnectivityOptionsQuery({
      variables: {
        input: {
          propertyId: selectedApartment?.propertyId,
        },
      },
      skip: !selectedApartment,
      onCompleted: (data) => {
        const recommendedProvider = data.fiberConnectivityOptions?.connectivityOptions?.find(
          (o) => o?.provider == data.fiberConnectivityOptions?.recommendedProvider,
        );
        if (!data.fiberConnectivityOptions?.isNewConnectionAvailable) {
          setMessage(
            `Ekki hægt að panta ljósleiðara fyrir þessa íbúð. Ástæða: ${data.fiberConnectivityOptions?.reason}`,
          );
          setSelectedProvider(undefined);
        } else if (recommendedProvider && !selectedProvider) {
          setMessage('');
          setSelectedProvider(recommendedProvider as ConnectionOptions);
        } else if (selectedProvider) {
          setSelectedProvider(
            data.fiberConnectivityOptions.connectivityOptions?.find(
              (o) => o?.provider == selectedProvider.provider,
            ) as ConnectionOptions,
          );
        }
      },
    });

  const properties = data?.connectionAvailabilityApartments;

  const onSelectApartment = (selected: ProviderApartment) => {
    setSelectedApartment(selected);
  };

  const onSubmit = () => {
    try {
      if (connectivityOptions && connectivityOptions.fiberConnectivityOptions) {
        const connectivityOptionsClone = cloneDeep(connectivityOptions);
        if (connectivityOptionsClone) {
          delete connectivityOptionsClone.__typename;
          delete connectivityOptionsClone.fiberConnectivityOptions?.__typename;
          delete connectivityOptionsClone.fiberConnectivityOptions?.connectivityOptions;
          const options = cloneDeep(
            connectivityOptions?.fiberConnectivityOptions?.connectivityOptions,
          );
          if (options) {
            for (let i = 0; i < options.length; i++) {
              delete options[i]!.__typename;
            }
          }
          updateFiberConnectivityOptions({
            variables: {
              input: {
                connectivityOptionsType: isCompanyOrder
                  ? ConnectivityOptionsType.Organization
                  : ConnectivityOptionsType.Individual,
                connectionSpeed,
                connectivityOptions: options,
                isNewConnectionAvailable:
                  connectivityOptions?.fiberConnectivityOptions?.isNewConnectionAvailable,
                reason: connectivityOptions?.fiberConnectivityOptions?.reason,
                recommendedProvider:
                  connectivityOptions?.fiberConnectivityOptions?.recommendedProvider,
              },
            },
            onCompleted: (data) => {
              const optimalProvider = data.updateFiberConnectivityOptions?.recommendedProvider;
              const connectivityOptions =
                data.updateFiberConnectivityOptions?.connectivityOptions?.find(
                  (item) => item?.provider === optimalProvider,
                );
              if (selectedApartment && optimalProvider) {
                onSelectProperty(selectedApartment, connectivityOptions as ConnectionOptions);
              }
            },
          });
        }
      }
    } catch (e) {
      setMessage('Gekk ekki að uppfæra þjónustuaðila');
    }
  };

  const reason = connectivityOptions?.fiberConnectivityOptions?.reason;

  return (
    <>
      {loading && <Box marginTop={5}>{t('property.fetchingProperties')}</Box>}
      {!loading && properties && properties.length > 0 && (
        <Box marginTop={5} style={{ marginRight: isMedium ? 0 : negativeMarginForCarousel }}>
          <Box display="flex" flexDirection="row">
            <Text variant="pLargeBold" marginRight={1} marginBottom={3}>
              {t('properties.title')}
            </Text>
            <Tooltip shouldShowOnHover>
              <CardBase borderColor="grey200" dottedShadow="none" hasBorder>
                <Box padding={2}>
                  <Text marginBottom={1} variant="pMediumBold">
                    {t('property.apartmentNumber')}
                  </Text>
                  <Text marginBottom={1} variant="pXSmallRegular">
                    {t('properties.subtitle')}
                  </Text>
                </Box>
              </CardBase>
            </Tooltip>
          </Box>
          <GridCarousel
            color={color}
            numberOnSlide={itemsPerPage}
            gridTemplate={{ sm: 2, md: 3, lg: 4, xl: 5 }}
            gridGap={{ sm: 2, lg: 3 }}
            backButtonHiddenTitle={t('dateGrid.prev')}
            nextButtonHiddenTitle={t('dateGrid.next')}
            scrollToSlide={apartmentSlide}
          >
            {properties
              ?.slice()
              ?.sort((a, b) => {
                const apartmentNumberA = a?.apartmentNumber ?? '';
                const apartmentNumberB = b?.apartmentNumber ?? '';

                return apartmentNumberA.localeCompare(apartmentNumberB);
              })
              ?.map((apartment) => {
                const isSelected = selectedApartment?.propertyId === apartment?.propertyId;
                return (
                  <GridItem key={apartment?.id} gridColumn={{ sm: 'span1' }}>
                    <Box
                      display="flex"
                      flexDirection="column"
                      justifyContent="space-between"
                      alignItems="stretch"
                      height="100%"
                      paddingX={2}
                      paddingY={1}
                      dottedShadow="small"
                      borderStyle="solid"
                      backgroundColor="white"
                      renderAs="button"
                      width="100%"
                      borderWidth="2px"
                      boxShadow={{
                        focusVisible: 'focused',
                        hover: isSelected ? 'none' : 'small',
                      }}
                      pointerEvents={isSelected ? 'none' : 'auto'}
                      borderColor={{
                        hover: color,
                        sm: isSelected ? color : 'grey200',
                      }}
                      onClick={() => {
                        if (apartment) onSelectApartment(apartment);
                      }}
                    >
                      {isSelected && loadingConnectivityOptions ? (
                        <Box
                          minHeight="100%"
                          width="100%"
                          display="flex"
                          justifyContent="center"
                          alignItems="center"
                        >
                          <LoadingIcon size={32} color={color} />
                        </Box>
                      ) : (
                        <>
                          <Box
                            display="flex"
                            justifyContent="space-between"
                            alignItems="center"
                            width="100%"
                          >
                            <Text renderAs="span" variant="pLargeBold">
                              {apartment?.apartmentNumber}
                            </Text>
                            <Text variant="pSmallRegular" style={{ fontSize: '12px' }}>
                              {apartment?.squareMeters}㎡
                            </Text>
                          </Box>
                          <Box display="flex" flexDirection="column">
                            <Text
                              variant="eyebrowSmall"
                              color="grey500"
                              style={{ fontWeight: 'normal' }}
                            >
                              {apartment?.usageText}
                            </Text>
                            <Text
                              variant="eyebrowSmall"
                              color="grey500"
                              style={{ fontWeight: 'normal' }}
                            >
                              {`Númer ${apartment?.propertyId}`}
                            </Text>
                          </Box>
                        </>
                      )}
                    </Box>
                  </GridItem>
                );
              })}
          </GridCarousel>

          <Box>
            {message && (
              <Box display={'flex'} flexDirection={'column'}>
                {reason === ConnectionReason.AlreadyActive && (
                  <Text variant="pLargeBold">{'Valið rými er þegar tengt við ljósleiðara'}</Text>
                )}
                {reason === ConnectionReason.SpaceNotApplicable && (
                  <Text variant="pLargeBold">
                    {isCompanyOrder
                      ? 'Valið rými er einstaklingsrými'
                      : 'Valið rými er atvinnurými'}
                  </Text>
                )}
                {message}
              </Box>
            )}

            {connectivityOptions &&
              connectivityOptions.fiberConnectivityOptions?.isNewConnectionAvailable &&
              reason === ConnectionReason.SpaceNotApplicable && (
                <Box>
                  Ekki hægt að panta Ljósleiðara frá {selectedProvider?.provider} fyrir þessa íbúð.
                  Vinsamlegast veldu annan birgja
                </Box>
              )}

            {reason === ConnectionReason.Ok && (
              <Box
                width="4/12"
                display="flex"
                justifyContent="flex-end"
                marginTop={5}
                marginRight={5}
                marginLeft="auto"
              >
                <MainButton
                  colorScheme={color}
                  dottedShadow="none"
                  icon="checkBox"
                  text={t('property.nextStep')}
                  onClick={() => onSubmit()}
                />
              </Box>
            )}
          </Box>
        </Box>
      )}
    </>
  );
};

export default inject('authentication')(observer(Properties));
